<template>
  <div class="slider" ref="slider">
    <div class="slider-group" ref="sliderGroup">
      <slot></slot>
    </div>
    <!--    轮播图上的小点-->
    <div class="dots" ref="dots">
      <span class="dot" v-for="(item, index) in dots" :class="{active:currentPageIndex === index}"
            :key="index"></span>
    </div>
  </div>
</template>

<script type="text/ecmascript-6">
  import BScroll from 'better-scroll'
  import {addClass} from 'common/js/dom.js'

  export default {
    props: {
      // 循环
      loop: {
        type: Boolean,
        default: true
      },
      // 自动轮播
      autoPlay: {
        type: Boolean,
        default: true
      },
      // 自动轮播的时间间隔
      interval: {
        type: Number,
        default: 1000
      }
    },
    data () {
      return {
        // 轮播图上的小点
        dots: [],
        // 当前第几页
        currentPageIndex: 0
      }
    },
    mounted () {
      // 等待DOM渲染完毕，better-scroll才开始计算
      setTimeout(() => {
        // 计算出轮播图总宽度
        this._setSliderWidth()
        // 轮播图索引小点
        this._initDots()
        // 初始化轮播图的样式及循环播放
        this._initSlider()
        // 是否自动轮播
        if (this.autoPlay) {
          this._play()
        }
      }, 1000)
      // 窗口大小改变的时候，重新计算slider的大小
      window.addEventListener('resize', () => {
        if (!this.slider) {
          return
        }
        this._setSliderWidth(true)
        this.slider.refresh()
      })
    },
    // 释放内存
    beforeDestroy () {
      clearTimeout(this.timer)
    },
    methods: {
      // 计算出轮播图片的总宽度
      _setSliderWidth (isResize) {
        // 获取轮播图片的DOM
        this.children = this.$refs.sliderGroup.children

        let width = 0
        // 轮播图界面的宽度
        let sliderWidth = this.$refs.slider.clientWidth
        for (let i = 0; i < this.children.length; i++) {
          let child = this.children[i]
          addClass(child, 'slider-item')
          child.style.width = sliderWidth + 'px'
          width += sliderWidth
        }
        // 如果可以循环滚动，那么就要克隆两张前后的图片，所以多加两个sliderWidth
        if (this.loop && !isResize) {
          width += 2 * sliderWidth
        }
        this.$refs.sliderGroup.style.width = width + 'px'
      },
      // 进行滑动初始化
      _initSlider () {
        this.slider = new BScroll(this.$refs.slider, {
          scrollX: true,
          scrollY: false,
          // 惯性
          momentum: false,
          // 开启snap
          snap: {
            // 循环
            loop: this.loop,
            // 手指滑动阀值大于0.3时滑动到下一页
            threshold: 0.3,
            // 切换的时间
            speed: 400
          }
        })
        // 给轮播图增加一个监听事件，当滑动结束的时候获取当前的页数
        this.slider.on('scrollEnd', () => {
          // pageIndex表示横向滚动到第几页
          let pageIndex = this.slider.getCurrentPage().pageX
          this.currentPageIndex = pageIndex
          if (this.autoPlay) {
            // 清除自动轮播，不然手动滑动的时候自动轮播还在进行，
            // 手动滑动之后不多久又会出现一个播放，效果不好
            clearTimeout(this.timer)
            this._play()
          }
        })
        // 在手动滑动之前清除自动轮播，不然会播放多次
        this.slider.on('beforeScrollStart', () => {
          if (this.autoPlay) {
            clearTimeout(this.timer)
          }
        })
      },
      // 初始化轮播图上的小点,它的数组长度就是图片长度，
      // 所以初始化时就设定好长度就可以了
      _initDots () {
        this.dots = new Array(this.children.length)
      },
      // 自动轮播
      _play () {
        let pageIndex = this.currentPageIndex + 1
        // 因为循环轮播，better-scroll自动在第一张和最后一张图片拷贝了一张图片，
        // 所以当走到倒数第一张的时候把页数重置为第一张
        if (pageIndex === this.children.length - 2) {
          pageIndex = 0
        }
        // 定时器定时改变页数
        this.timer = setTimeout(() => {
          this.slider.goToPage(pageIndex, 0, 1000)
        }, this.interval)
      }
    }
  }
</script>

<style lang="stylus" rel="stylesheet/stylus" scoped>
  @import "~common/stylus/variable"
  .slider
    position: relative
    min-height: 1px

    .slider-group
      overflow: hidden
      white-space: nowrap

      .slider-item
        float: left
        box-sizing: border-box
        text-align: center
        overflow: hidden

        a
          display: block
          width: 100%
          overflow: hidden
          text-decoration: none

        img
          display: block
          width: 100%

    .dots
      position absolute
      right: 0
      left: 0
      bottom: 12px
      text-align: center
      font-size: 0

      .dot
        display: inline-block
        margin: 0 4px
        width: 8px
        height: 8px
        border-radius: 50%
        background: $color-text-l

        &.active
          width: 20px
          border-radius: 5px
          background: blue
</style>
